<?php

/**

 * [WeEngine System] Copyright (c) 2014 WE7.CC

 * WeEngine is NOT a free software, it under the license terms, visited http://www.qincewang.com/ for more details.

 */

defined('IN_IA') or exit('Access Denied');



load()->model('extension');

load()->model('cloud');

load()->model('cache');

load()->func('file');

$dos = array('installed', 'check', 'prepared', 'install', 'upgrade', 'uninstall', 'designer', 'permission', 'batch-install', 'info', 'recycle');

$do = in_array($do, $dos) ? $do : 'installed';



$points = ext_module_bindings();

$sysmodules = system_modules();



if ($do == 'recycle') {

	$operate = $_GPC['op'];

	$name = trim($_GPC['name']);

	if ($operate == 'delete') {

		pdo_insert('modules_recycle', array('modulename' => $name));

		message('模块已放入回收站', url('extension/module/prepared', array('status' => 'recycle')), 'success');

	} elseif ($operate == 'recover') {

		pdo_delete('modules_recycle', array('modulename' => $name));

		message('模块恢复成功', url('extension/module/install', array('m' => $name)), 'success');

	}

	template('extension/module');

}

if($do == 'batch-install') {

	if(empty($_W['isfounder'])) {

		message('您没有安装模块的权限', '', 'error');

	}

	

	if($_W['ispost']) {

		$modulename = $_GPC['m_name'];

		if(pdo_fetchcolumn("SELECT mid FROM " . tablename('modules') . " WHERE name = :name", array(':name' => $modulename))) {

			exit('error');

		}

		

		$modulepath = IA_ROOT . '/addons/' . $modulename . '/';

		$manifest = ext_module_manifest($modulename);

		if (!empty($manifest)) {

			$r = cloud_m_prepare($modulename);

			if(is_error($r)) {

				exit('error');

			}

		}

		if(empty($manifest)) {

			exit('error');

		}

		manifest_check($modulename, $manifest);

		if(pdo_fetchcolumn("SELECT mid FROM " . tablename('modules') . " WHERE name = :name", array(':name' => $manifest['application']['identifie']))) {

			exit('error');

		}

		if(!file_exists($modulepath . 'processor.php') && !file_exists($modulepath . 'module.php') && !file_exists($modulepath . 'receiver.php') && !file_exists($modulepath . 'site.php')) {

			exit('error');

		}

		$module = ext_module_convert($manifest);

		ext_module_clean($modulename);

		$bindings = array_elements(array_keys($points), $module, false);

		foreach($points as $p => $row) {

			unset($module[$p]);

			if(is_array($bindings[$p]) && !empty($bindings[$p])) {

				foreach($bindings[$p] as $entry) {

					$entry['module'] = $manifest['application']['identifie'];

					$entry['entry'] = $p;

					pdo_insert('modules_bindings', $entry);

				}

			}

		}

		$module['permissions'] = iserializer($module['permissions']);

		if(pdo_insert('modules', $module)) {

			load()->model('module');

			module_build_privileges();

			cache_build_account_modules();

			if(strexists($manifest['install'], '.php')) {

				if(file_exists($modulepath . $manifest['install'])) {

					include_once $modulepath . $manifest['install'];

				}

			} else {

				pdo_run($manifest['install']);

			}

			update_handle($module['name']);

			exit('success');

		} else {

			exit('error');

		}

	}

}



if($do == 'info') {

	$m = trim($_GPC['m']);

	if($_W['isajax']) {

		$data = pdo_fetch('SELECT name, title, ability, description FROM ' . tablename('modules') . ' WHERE name = :m', array(':m' => $m));

		exit(json_encode($data));

	} else {

		if(checksubmit('submit')) {

			$update = array();

			!empty($_GPC['title']) && $update['title'] = $_GPC['title'];

			!empty($_GPC['ability']) && $update['ability'] = $_GPC['ability'];

			!empty($_GPC['description']) && $update['description'] = $_GPC['description'];

			if(!empty($update)) {

				pdo_update('modules', $update, array('name' => $m));

				cache_build_account_modules();

			}

			$sysmodules = system_modules();

			if(in_array($m, $sysmodules)) {

				$root = IA_ROOT . '/framework/builtin/' . $m;

			} else {

				$root = IA_ROOT . '/addons/' . $m;

			}

			if($_FILES['icon'] && $_FILES['icon']['error'] == '0' && !empty($_FILES['icon']['tmp_name'])) {

				$icon = $_FILES['icon']['tmp_name'];

			}

			if($_FILES['preview'] && $_FILES['preview']['error'] == '0' && !empty($_FILES['preview']['tmp_name'])) {

				$preview = $_FILES['preview']['tmp_name'];

			}

			load()->func('file');

			mkdirs($root);

			if($icon) {

				file_move($icon, "{$root}/icon-custom.jpg");

			}

			if($preview) {

				file_move($preview, "{$root}/preview-custom.jpg");

			}

			message('更新模块信息成功', referer(), 'success');

		}

	}

}



if($do == 'installed') {

	$_W['page']['title'] = '已安装的模块 - 模块 - 扩展';

	load()->model('module');

	$modtypes = module_types();

	$modules = pdo_fetchall("SELECT * FROM " . tablename('modules') .' ORDER BY `issystem` DESC, `mid` ASC', array(), 'mid');

	if (!empty($modules)) {

		foreach ($modules as $mid => $module) {

			$manifest = ext_module_manifest($module['name']);

			$modules[$mid]['official'] = empty($module['issystem']) && (strexists($module['author'], 'WeEngine Team') || strexists($module['author'], '微擎团队'));

			$modules[$mid]['description'] = strip_tags($module['description']);

			if(is_array($manifest) && ver_compare($module['version'], $manifest['application']['version']) == '-1') {

				$modules[$mid]['upgrade'] = true;

			}

						if(in_array($module['name'], $sysmodules)) {

				$modules[$mid]['imgsrc'] = '../framework/builtin/' . $module['name'] . '/icon-custom.jpg';

				if(!file_exists($modules[$mid]['imgsrc'])) {

					$modules[$mid]['imgsrc'] = '../framework/builtin/' . $module['name'] . '/icon.jpg';

				}

			} else {

				$modules[$mid]['imgsrc'] = '../addons//' . $module['name'] . '/icon-custom.jpg';

				if(!file_exists($modules[$mid]['imgsrc'])) {

					$modules[$mid]['imgsrc'] = '../addons/' . $module['name'] . '/icon.jpg';

				}

			}

		}

	}

	$sysmodules = implode("', '", $sysmodules);

	template('extension/module');

}



if ($do == 'check') {

	if ($_W['isajax']) {

		$foo = $_GPC['foo'];

		$r = cloud_prepare();

		if (is_error($r)) {

			exit('cloud service is unavailable');

		}

		if ($foo == 'upgrade') {

			$mods = array();



			$ret = cloud_m_query();



			if (!is_error($ret)) {

				foreach ($ret as $k => $v) {

					$mods[$k] = array(

						'from' => 'cloud',

						'version' => $v['version'],

						'name' => $v['name'],

						'branches' => $v['branches'],

						'site_branch' => $v['branches'][$v['branch']],

					);

				}

				$mods['pirate_apps'] = array_values($v['pirate_apps']);

			}

			if (!empty($mods)) {

				exit(json_encode($mods));

			} else {

				exit(json_encode(array('')));

			}

		} else {

			$moduleids = array();

			$modules = pdo_fetchall("SELECT `name` FROM " . tablename('modules') . ' ORDER BY `issystem` DESC, `mid` ASC');

			if (!empty($modules)) {

				foreach ($modules as $m) {

					$moduleids[] = $m['name'];

				}

			}

			

			$ret = cloud_m_query();



			if (!is_error($ret)) {

				$cloudUninstallModules = array();

				foreach ($ret as $k => $v) {

					if (!in_array(strtolower($k), $moduleids)) {

						$v['name'] = $k;

						$cloudUninstallModules[] = $v;

						$moduleids[] = $k;

					}

				}

				foreach ($cloudUninstallModules as &$cloudUninstallModule) {

					$cloudUninstallModule['description'] = strip_tags($cloudUninstallModule['description']);

				}

				exit(json_encode($cloudUninstallModules));

			}

		}

	}

	exit('failure');

}



if($do == 'prepared') {

	$_W['page']['title'] = '安装模块 - 模块 - 扩展';

	$status = $_GPC['status'];

	$recycle_modules = pdo_getall('modules_recycle', array(), array(), 'modulename');

	$recycle_modules = array_keys($recycle_modules);

	$moduleids = array();

	$modules = pdo_fetchall("SELECT `name` FROM " . tablename('modules') . ' ORDER BY `issystem` DESC, `mid` ASC');

	if(!empty($modules)) {

		foreach($modules as $m) {

			$moduleids[] = $m['name'];

		}

	}

	$path = IA_ROOT . '/addons/';

	if (is_dir($path)) {

		$localUninstallModules_noso = array();

		$localUninstallModules_title = array();

		$localUninstallModules = array();

		if ($handle = opendir($path)) {

			while (false !== ($modulepath = readdir($handle))) {

				$manifest = ext_module_manifest($modulepath);

				if (!empty($status) && in_array($manifest['application']['identifie'], $recycle_modules) || empty($status) && !in_array($manifest['application']['identifie'], $recycle_modules)) {

					if (is_array($manifest) && !empty($manifest['application']['identifie']) && !in_array($manifest['application']['identifie'], $moduleids)) {

						$m = ext_module_convert($manifest);

						$localUninstallModules[$m['name']] = $m;

						if ($m['issolution'] <> 1) {

							$localUninstallModules_noso[$m['name']] = $m;

							$localUninstallModules_title[$m['name']] = $m['title'];

						}

						$moduleids[] = $manifest['application']['identifie'];

					}

				}

			}

		}

	}

	$prepare_module = json_encode(array_keys($localUninstallModules_noso));

	$prepare_module_title = json_encode($localUninstallModules_title);

	template('extension/module');

}



if($do == 'permission') {

	load()->model('module');

	$id = $_GPC['id'];

	$module = pdo_fetch("SELECT mid, name FROM " . tablename('modules') . " WHERE name = :name", array(':name' => $id));

	if(!empty($module[''])) {}

	$isinstall = false;

	$from = '';

		cache_load('modules');

	if(!empty($module)) {

		$module = $_W['modules'][$module['name']];

				if (empty($module)) {

			$data = pdo_getall('modules');

			$update = array();

			foreach ($data as &$mod) {

				unset($mod['permission']);

				$mod['subscribes'] = unserialize($mod['subscribes']);

				$mod['handles'] = unserialize($mod['handles']);

				$update[$mod['name']] = $mod;

			}

			cache_write('modules', $update);

			cache_load('modules');

			$module = $_W['modules'][$module['name']];

		}

		$bindings = pdo_fetchall('SELECT * FROM ' . tablename('modules_bindings') . ' WHERE `module`=:module', array(':module' => $id));

		if(!empty($bindings)) {

			foreach($bindings as $entry) {

				$module[$entry['entry']][] = array_elements(array('title', 'do', 'direct', 'state'), $entry);

			}

		}

		$manifest = ext_module_manifest($module['name']);

		if(is_array($manifest) && ver_compare($module['version'], $manifest['application']['version']) == -1) {

			$module['upgrade'] = 1;

		}

		$isinstall = true;

		$from = 'installed';

		if(in_array($module['name'], $sysmodules)) {

			$issystem = 1;

		}

		$manifest = ext_module_manifest($id);

		$from = 'local';

	}

	if (empty($module)) {

		message('你访问的模块不存在. 或许你愿意去微擎云服务平台看看. ', 'http://www.qincewang.com/web/index.php?keyword=' . $_GPC['title']);

	}

	$module['isinstall'] = $isinstall;

	$module['from'] = $from;

	$mtypes = ext_module_msg_types();

	$modtypes = module_types();

	$issystem = $module['issystem'];

	if($issystem) {

		$path = '../framework/builtin/' . $module['name'];

	} else {

		$path = '../addons/' . $module['name'];

	}

	$cion = $path . '/icon-custom.jpg';

	$preview = $path . '/preview-custom.jpg';

	if(!file_exists($cion)) {

		$cion = $path . '/icon.jpg';

	}

	if(!file_exists($preview)) {

		$preview = $path . '/preview.jpg';

	}

	template('extension/permission');

}



if($do == 'install') {

	if (empty($_W['isfounder'])) {

		message('您没有安装模块的权限', '', 'error');

	}

	$modulename = $_GPC['m'];

	if (pdo_fetchcolumn("SELECT mid FROM " . tablename('modules') . " WHERE name = :name", array(':name' => $modulename))) {

		message('模块已经安装或是唯一标识已存在！', '', 'error');

	}



	$manifest = ext_module_manifest($modulename);

	if (!empty($manifest)) {

		$r = cloud_m_prepare($modulename);

		if (is_error($r)) {

			message($r['message'], url('extension/module/prepared'), 'error');

		}

	}



	if (empty($manifest)) {

		$r = cloud_prepare();

		if (is_error($r)) {

			message($r['message'], url('cloud/profile'), 'error');

		}

		$info = cloud_m_info($modulename);

		if (!is_error($info)) {

			if (empty($_GPC['flag'])) {

				header('location: ' . url('cloud/process', array('m' => $modulename)));

				exit;

			} else {

				define('ONLINE_MODULE', true);

				$packet = cloud_m_build($modulename);

				$manifest = ext_module_manifest_parse($packet['manifest']);

			}

		} else {

			message($info['message'], '', 'error');

		}

	}



	if (empty($manifest)) {

		message('模块安装配置文件不存在或是格式不正确，请刷新重试！', '', 'error');

	}



	manifest_check($modulename, $manifest);

	$modulepath = IA_ROOT . '/addons/' . $modulename . '/';

	if (!file_exists($modulepath . 'processor.php') && !file_exists($modulepath . 'module.php') && !file_exists($modulepath . 'receiver.php') && !file_exists($modulepath . 'site.php')) {

		message('模块处理文件 site.php, processor.php, module.php, receiver.php 一个都不存在 ！', '', 'error');

	}

	$module = ext_module_convert($manifest);

	$groups = uni_groups();

	if (!$_W['ispost'] || empty($_GPC['flag'])) {

		template('extension/select-groups');

		exit;

	}

	$post_groups = $_GPC['group'];

	ext_module_clean($modulename);

	$bindings = array_elements(array_keys($points), $module, false);

	foreach ($points as $p => $row) {

		unset($module[$p]);

		if (is_array($bindings[$p]) && !empty($bindings[$p])) {

			foreach ($bindings[$p] as $entry) {

				$entry['module'] = $manifest['application']['identifie'];

				$entry['entry'] = $p;

				pdo_insert('modules_bindings', $entry);

			}

		}

	}

	$module['permissions'] = iserializer($module['permissions']);

	$module_subscribe_success = true;

	if (!empty($module['subscribes'])) {

		$subscribes = iunserializer($module['subscribes']);

		if (!empty($subscribes)) {

			$module_subscribe_success = ext_check_module_subscribe($module['name']);

		}

	}

	if (!empty($info['version']['cloud_setting'])) {

		$module['settings'] = 2;

	}

	if (pdo_insert('modules', $module)) {

		if (strexists($manifest['install'], '.php')) {

			if (file_exists($modulepath . $manifest['install'])) {

				include_once $modulepath . $manifest['install'];

			}

		} else {

			pdo_run($manifest['install']);

		}

		update_handle($module['name']);



				if (defined('ONLINE_MODULE')) {

			ext_module_script_clean($module['name'], $manifest);

		}



		if ($_GPC['flag'] && !empty($post_groups) && $module['name']) {

			foreach ($post_groups as $post_group) {

				$item = pdo_fetch("SELECT id,name,modules FROM " . tablename('uni_group') . " WHERE id = :id", array(':id' => intval($post_group)));

				if (empty($item)) {

					continue;

				}

				$item['modules'] = iunserializer($item['modules']);

				if (in_array($module['name'], $item['modules'])) {

					continue;

				}

				$item['modules'][] = $module['name'];

				$item['modules'] = iserializer($item['modules']);

				pdo_update('uni_group', $item, array('id' => $post_group));

			}

		}

		load()->model('module');

		module_build_privileges();

		cache_build_module_subscribe_type();

		cache_build_account_modules();

		if (empty($module_subscribe_success)) {

			message('模块安装成功, 请按照【公众号服务套餐】【用户组】来分配权限！模块订阅消息有错误，系统已禁用该模块的订阅消息，详细信息请查看 <div><a class="btn btn-primary" style="width:80px;" href="' . url('extension/subscribe/subscribe') . '">订阅管理</a> &nbsp;&nbsp;<a class="btn btn-default" href="' . url('extension/module') . '">返回模块列表</a></div>', '', 'tips');

		} else {

			message('模块安装成功, 请按照【公众号服务套餐】【用户组】来分配权限！', url('extension/module'), 'success');

		}

	} else {

		message('模块安装失败, 请联系模块开发者！');

	}

}



if ($do == 'uninstall') {

	if (empty($_W['isfounder'])) {

		message('您没有卸载模块的权限', '', 'error');

	}

	$id = $_GPC['id'];



	$module = pdo_fetch("SELECT `name`, `isrulefields`, `issystem`, `version` FROM " . tablename('modules') . " WHERE name = :name", array(':name' => $id));



	if (empty($module)) {

		message('模块已经被卸载或是不存在！', '', 'error');

	}



	if (!empty($module['issystem'])) {

		message('系统模块不能卸载！', '', 'error');

	}

	if ($module['isrulefields'] && !isset($_GPC['confirm'])) {

		message('卸载模块时同时删除规则数据吗, 删除规则数据将同时删除相关规则的统计分析数据？<div><a class="btn btn-primary" style="width:80px;" href="' . url('extension/module/uninstall', array('id' => $_GPC['id'], 'confirm' => 1)) . '">是</a> &nbsp;&nbsp;<a class="btn btn-default" style="width:80px;" href="' . url('extension/module/uninstall', array('id' => $_GPC['id'], 'confirm' => 0)) . '">否</a></div>', '', 'tips');

	} else {

		$modulepath = IA_ROOT . '/addons/' . $id . '/';

		$manifest = ext_module_manifest($module['name']);

		if (empty($manifest)) {

			$r = cloud_prepare();

			if (is_error($r)) {

				message($r['message'], url('cloud/profile'), 'error');

			}



			$packet = cloud_m_build($module['name'], $do);



			if ($packet['sql']) {

				pdo_run(base64_decode($packet['sql']));

			} elseif ($packet['script']) {

				$uninstall_file = $modulepath . TIMESTAMP . '.php';

				file_put_contents($uninstall_file, base64_decode($packet['script']));

				require($uninstall_file);

				unlink($uninstall_file);

			}

		} elseif (!empty($manifest['uninstall'])) {

			if (strexists($manifest['uninstall'], '.php')) {

				if (file_exists($modulepath . $manifest['uninstall'])) {

					require($modulepath . $manifest['uninstall']);

				}

			} else {

				pdo_run($manifest['uninstall']);

			}

		}



		ext_module_clean($id, $_GPC['confirm'] == '1');



		cache_build_account_modules();



		cache_build_module_subscribe_type();



		pdo_insert('modules_recycle', array('modulename' => $module['name']));



		message('模块已放入回收站！', url('extension/module'), 'success');

	}

}



if($do == 'upgrade') {

	$id = $_GPC['m'];

	$module = pdo_fetch("SELECT mid, name, version FROM " . tablename('modules') . " WHERE name = :name", array(':name' => $id));

	if (empty($module)) {

		message('模块已经被卸载或是不存在！', '', 'error');

	}



	$type = $_GPC['type'];

	$modulepath = IA_ROOT . '/addons/' . $id . '/';



		if ($type == 'getinfo') {

		$manifest = '';

	} else {

		$manifest = ext_module_manifest($module['name']);

	}



	if (empty($manifest)) {

		$r = cloud_prepare();

		if (is_error($r)) {

			message($r['message'], url('cloud/profile'), 'error');

		}



		$info = cloud_m_upgradeinfo($id);

		

		if ($_W['isajax'] && $type == 'getinfo') {

			if ($info['free']) {

				foreach ($info['branches'] as &$branch) {

					$branch['upgrade_price'] = 0;

				}

			}

			message($info, '', 'ajax');

		}

		if (is_error($info)) {

			message($info['message'], referer(), 'error');

		}



		if (!is_error($info)) {

			if (empty($_GPC['flag'])) {

				if (intval($_GPC['branch']) > $info['version']['branch_id']) {

					header('location: ' . url('cloud/redirect/buybranch', array('m' => $id, 'branch' => intval($_GPC['branch']), 'is_upgrade' => 1)));

					exit;

				}

				header('location: ' . url('cloud/process', array('m' => $id, 'is_upgrade' => 1)));

				exit;

			} else {

				define('ONLINE_MODULE', true);

				$packet = cloud_m_build($id);

				$manifest = ext_module_manifest_parse($packet['manifest']);

			}

		}

	}

	

	if (empty($manifest)) {

		message('模块安装配置文件不存在或是格式不正确！', '', 'error');

	}

	manifest_check($id, $manifest);



	if (!file_exists($modulepath . 'processor.php') && !file_exists($modulepath . 'module.php') && !file_exists($modulepath . 'receiver.php') && !file_exists($modulepath . 'site.php')) {

		message('模块处理文件 site.php, processor.php, module.php, receiver.php 一个都不存在 ！', '', 'error');

	}

	$module = ext_module_convert($manifest);

	unset($module['name']);

	unset($module['id']);

	$bindings = array_elements(array_keys($points), $module, false);

	foreach ($points as $p => $row) {

		unset($module[$p]);

		if (is_array($bindings[$p]) && !empty($bindings[$p])) {

			foreach ($bindings[$p] as $entry) {

				$entry['module'] = $manifest['application']['identifie'];

				$entry['entry'] = $p;

				if ($entry['title'] && $entry['do']) {

										$delete_do[] = $entry['do'];

					$delete_title[] = $entry['title'];



					$sql = 'SELECT * FROM ' . tablename('modules_bindings') . ' WHERE `module`=:module AND `entry`=:entry AND `title`=:title AND `do`=:do';

					$pars = array();

					$pars[':module'] = $manifest['application']['identifie'];

					$pars[':entry'] = $p;

					$pars[':title'] = $entry['title'];

					$pars[':do'] = $entry['do'];

					$rec = pdo_fetch($sql, $pars);

					if (!empty($rec)) {

						pdo_update('modules_bindings', $entry, array('eid' => $rec['eid']));

						continue;

					}

				} elseif ($entry['call']) {

					$delete_call[] = $entry['call'];



					$sql = 'SELECT * FROM ' . tablename('modules_bindings') . ' WHERE `module`=:module AND `entry`=:entry AND `call`=:call';

					$pars = array();

					$pars[':module'] = $manifest['application']['identifie'];

					$pars[':entry'] = $p;

					$pars[':call'] = $entry['call'];

					$rec = pdo_fetch($sql, $pars);

					if (!empty($rec)) {

						pdo_update('modules_bindings', $entry, array('eid' => $rec['eid']));

						continue;

					}

				}

				pdo_insert('modules_bindings', $entry);

			}

						if (!empty($delete_do)) {

				pdo_query('DELETE FROM ' . tablename('modules_bindings') . " WHERE module = :module AND entry = :entry AND `call` = '' AND do NOT IN ('" . implode("','", $delete_do) . "')", array(':module' => $manifest['application']['identifie'], ':entry' => $p));

				unset($delete_do);

			}

			if (!empty($delete_title)) {

				pdo_query('DELETE FROM ' . tablename('modules_bindings') . " WHERE module = :module AND entry = :entry AND `call` = '' AND title NOT IN ('" . implode("','", $delete_title) . "')", array(':module' => $manifest['application']['identifie'], ':entry' => $p));

				unset($delete_title);

			}

			if (!empty($delete_call)) {

				pdo_query('DELETE FROM ' . tablename('modules_bindings') . " WHERE module = :module AND  entry = :entry AND do = '' AND title = '' AND `call` NOT IN ('" . implode("','", $delete_call) . "')", array(':module' => $manifest['application']['identifie'], ':entry' => $p));

				unset($delete_call);

			}

		}

	}

	if (!empty($manifest['upgrade'])) {

		if (strexists($manifest['upgrade'], '.php')) {

			if (file_exists($modulepath . $manifest['upgrade'])) {

				include_once $modulepath . $manifest['upgrade'];

			}

		} else {

			pdo_run($manifest['upgrade']);

		}

	}

		if (defined('ONLINE_MODULE')) {

		ext_module_script_clean($id, $manifest);

	}

	

	$module['permissions'] = iserializer($module['permissions']);

	

	if (!empty($info['version']['cloud_setting'])) {

		$module['settings'] = 2;

	} else {

		if (empty($manifest['application']['setting'])) {

			$module['settings'] = 0;

		} else {

			$module['settings'] = 1;

		}

	}

	pdo_update('modules', $module, array('name' => $id));

	cache_build_account_modules();

	if (!empty($module['subscribes'])) {

		$module_subscribe_success = ext_check_module_subscribe($module['name']);

	}

	cache_delete('cloud:transtoken');

	if ($_GPC['flag'] == 1) {

		message('模块更新成功！ <br> 由于数据库更新, 可能会产生多余的字段. 你可以按照需要删除.<div><a class="btn btn-primary" href="' . url('system/database/trim') . '">现在去删除</a>&nbsp;&nbsp;&nbsp;<a class="btn btn-default" href="' . url('extension/module/') . '">返回模块列表</a></div>', '', 'success');

	} else {

		message('模块更新成功！', referer(), 'success');

	}

}



if($do == 'designer') {

	if(empty($_W['isfounder'])) {

		message('您没有设计新模块的权限', '', 'error');

	}



	$_W['page']['title'] = '设计新模块 - 模块 - 扩展';

	load()->model('module');

	$available = array();

	$available['download'] = class_exists('ZipArchive');

	$available['create'] = @is_writable(IA_ROOT . '/addons');



	$mtypes = ext_module_msg_types();

	$modtypes = module_types();

	$versions = array();

	$versions[] = '0.6';



	$m = array();

	$m['platform'] = array();

	$m['platform']['subscribes'] = array();

	$m['platform']['handles'] = array();

	$m['site'] = array();

	$m['versions'] = array();

	if(checksubmit() && $available[$_GPC['method']]) {

		$m['application']['name'] = trim($_GPC['application']['name']);

		if(empty($m['application']['name']) || preg_match('/\*\/|\/\*|eval|\$\_/i', $m['application']['name'])) {

			message('请输入有效的模块名称. ');

		}

		$m['application']['identifie'] = trim($_GPC['application']['identifie']);

		if(empty($m['application']['identifie']) || !preg_match('/^[a-z][a-z\d_]+$/i', $m['application']['identifie'])) {

			message('必须输入模块标识符(仅支持字母和数字, 且只能以字母开头). ');

		}

		$m['application']['version'] = trim($_GPC['application']['version']);

		if(empty($m['application']['version']) || !preg_match('/^[\d\.]+$/i', $m['application']['version'])) {

			message('必须输入模块版本号(仅支持数字和句点). ');

		}

		$m['application']['ability'] = trim($_GPC['application']['ability']);

		if(empty($m['application']['ability'])) {

			message('必须输入模块功能简述. ');

		}

		$m['application']['type'] = array_key_exists($_GPC['application']['type'], $modtypes) ? $_GPC['application']['type'] : 'other';

		$m['application']['description'] = trim($_GPC['application']['description']);

		$m['application']['author'] = trim($_GPC['application']['author']);

		if(preg_match('/\*\/|\/\*|eval|\$\_/i', $m['application']['author'])) {

			message('请输入有效的模块作者');

		}

		$m['application']['url'] = trim($_GPC['application']['url']);

		if(preg_match('/\*\/|\/\*|eval|\$\_/i', $m['application']['url'])) {

			message('请输入有效的模块发布页');

		}

		$m['application']['setting'] = $_GPC['application']['setting'] == 'true';

		if(is_array($_GPC['subscribes'])) {

			foreach($_GPC['subscribes'] as $s) {

				if(array_key_exists($s, $mtypes)) {

					$m['platform']['subscribes'][] = $s;

				}

			}

		}

		if(is_array($_GPC['handles'])) {

			foreach($_GPC['handles'] as $s) {

				if(array_key_exists($s, $mtypes) && $s != 'unsubscribe') {

					$m['platform']['handles'][] = $s;

				}

			}

		}

		$m['platform']['rule'] = $_GPC['platform']['rule'] == 'true';

		if($m['platform']['rule']) {

			if(!in_array('text', $m['platform']['handles'])) {

				$m['platform']['handles'][] = 'text';

			}

		}

		$m['platform']['card'] = $_GPC['platform']['card'] == 'true';

		$m['bindings'] = array();

		foreach($points as $p => $row) {

			if(!is_array($_GPC['bindings'][$p]['titles'])) {

				continue;

			}

			foreach($_GPC['bindings'][$p]['titles'] as $key => $t) {

				$entry = array();

				$entry['title'] = trim($t);

				$entry['do'] = $_GPC['bindings'][$p]['dos'][$key];

				$entry['state'] = $_GPC['bindings'][$p]['state'][$key];

				$entry['direct'] = $_GPC['bindings'][$p]['direct'][$key] == 'true';

				if(!empty($entry['title']) && preg_match('/^[a-z\d]+$/i', $entry['do'])) {

					$m['bindings'][$p][] = $entry;

				}

			}

		}

				$permission = trim($_GPC['permission']);

		if(!empty($permission)) {

			$permission = str_replace(array('：'), array(':'), $permission);

			$permission = explode("\n", $permission);

			$arr = array();

			foreach($permission as $li) {

				$li = trim($li);

				$li = explode(':', $li);

				if(!empty($li[0]) && !empty($li[1])) {

					$arr[] = array('title' => $li[0], 'permission' => $li[1]);

				}

			}

			$m['permission'] = $arr;

		}

		if(is_array($_GPC['versions'])) {

			foreach($_GPC['versions'] as $ver) {

				if(in_array($ver, $versions)) {

					$m['versions'][] = $ver;

				}

			}

		}

		$m['install'] = trim($_GPC['install']);

		$m['uninstall'] = trim($_GPC['uninstall']);

		$m['upgrade'] = trim($_GPC['upgrade']);

		if($_FILES['icon'] && $_FILES['icon']['error'] == '0' && !empty($_FILES['icon']['tmp_name'])) {

			$m['icon'] = $_FILES['icon']['tmp_name'];

		}

		if($_FILES['preview'] && $_FILES['preview']['error'] == '0' && !empty($_FILES['preview']['tmp_name'])) {

			$m['preview'] = $_FILES['preview']['tmp_name'];

		}

		

		$manifest = manifest($m);

		$mDefine = define_module($m);

		$pDefine = define_processor($m);

		$rDefine = define_receiver($m);

		$sDefine = define_site($m);

		$ident = strtolower($m['application']['identifie']);

		

		if ($_GPC['method'] == 'create') {

			load()->func('file');

			$mRoot = IA_ROOT . "/addons/{$ident}";

			if(file_exists($mRoot)) {

				message("目标位置 {$mRoot} 已存在, 请更换标识或删除现有内容. ");

			}

			mkdirs($mRoot);

			f_write("{$mRoot}/manifest.xml", $manifest);

			if($mDefine) {

				f_write("{$mRoot}/module.php", $mDefine);

			}

			if($pDefine) {

				f_write("{$mRoot}/processor.php", $pDefine);

			}

			if($rDefine) {

				f_write("{$mRoot}/receiver.php", $rDefine);

			}

			if($sDefine) {

				f_write("{$mRoot}/site.php", $sDefine);

			}

			mkdirs("{$mRoot}/template");

			if($m['application']['setting']) {

				f_write("{$mRoot}/template/setting.html", "{template 'common/header'}\r\n这里定义页面内容\r\n{template 'common/footer'}");

			}

			if($m['icon']) {

				file_move($m['icon'], "{$mRoot}/icon.jpg");

			}

			if($m['preview']) {

				file_move($m['preview'], "{$mRoot}/preview.jpg");

			}

			message("生成成功. 请访问 {$mRoot} 继续实现你的模块.", 'refresh');

			die;

		}

		if($_GPC['method'] == 'download') {

			$fname = IA_ROOT . "/data/tmp.zip";

			$zip = new ZipArchive();

			$zip->open($fname, ZipArchive::CREATE);

			$zip->addFromString('manifest.xml', $manifest);

			if($mDefine) {

				$zip->addFromString('module.php', $mDefine);

			}

			if($pDefine) {

				$zip->addFromString('processor.php', $pDefine);

			}

			if($rDefine) {

				$zip->addFromString('receiver.php', $rDefine);

			}

			if($sDefine) {

				$zip->addFromString('site.php', $sDefine);

			}

			$zip->addEmptyDir('template');

			if($m['application']['setting']) {

				$zip->addFromString("template/setting.html", "{template 'common/header'}\r\n这里定义页面内容\r\n{template 'common/footer'}");

			}

			if($m['icon']) {

				$zip->addFile($m['icon'], 'icon.jpg');

				

			}

			if($m['preview']) {

				$zip->addFile($m['preview'], 'preview.jpg');

				

			}

			$zip->close();

			header('content-type: application/zip');

			header('content-disposition: attachment; filename="' . $ident . '.zip"');

			readfile($fname);

			@unlink($m['icon']);

			@unlink($m['preview']);

			@unlink($fname);

		}

	}

	template('extension/designer');

}







function manifest_check($id, $m) {

	if(is_string($m)) {

		message('模块配置项定义错误, 具体错误内容为: <br />' . $m);

	}

	if(empty($m['application']['name'])) {

		message('模块名称未定义. ');

	}

	if(empty($m['application']['identifie']) || !preg_match('/^[a-z][a-z\d_]+$/i', $m['application']['identifie'])) {

		message('模块标识符未定义或格式错误(仅支持字母和数字, 且只能以字母开头). ');

	}

	if(strtolower($id) != strtolower($m['application']['identifie'])) {

		message('模块名称定义与模块路径名称定义不匹配. ');

	}

	if(empty($m['application']['version']) || !preg_match('/^[\d\.]+$/i', $m['application']['version'])) {

		message('模块版本号未定义(仅支持数字和句点). ');

	}

	if(empty($m['application']['ability'])) {

		message('模块功能简述未定义. ');

	}

	if($m['platform']['isrulefields'] && !in_array('text', $m['platform']['handles'])) {

		message('模块功能定义错误, 嵌入规则必须要能够处理文本类型消息. ');

	}

	if((!empty($m['cover']) || !empty($m['rule'])) && !$m['platform']['isrulefields']) {

		message('模块功能定义错误, 存在封面或规则功能入口绑定时, 必须要嵌入规则. ');

	}

	global $points;

	foreach($points as $p => $row) {

		if(is_array($m[$p])) {

			foreach($m[$p] as $o) {

				if(trim($o['title']) == ''  || !preg_match('/^[a-z\d]+$/i', $o['do']) && empty($o['call'])) {

					message($row['title'] . ' 扩展项功能入口定义错误, (操作标题[title], 入口方法[do])格式不正确.');

				}

			}

		}

	}

		if(is_array($m['permissions']) && !empty($m['permissions'])) {

		foreach($m['permissions'] as $permission) {

			if(trim($permission['title']) == ''  || !preg_match('/^[a-z\d_]+$/i', $permission['permission'])) {

				message("名称为： {$permission['title']} 的权限标识格式不正确,请检查标识名称或标识格式是否正确");

			}

		}

	}

	if(!is_array($m['versions'])) {

		message('兼容版本格式错误. ');

	}

}



function manifest($m) {

	$versions = implode(',', $m['versions']);

	$setting = $m['application']['setting'] ? 'true' : 'false';

	$subscribes = '';

	foreach($m['platform']['subscribes'] as $s) {

		$subscribes .= "\r\n\t\t\t<message type=\"{$s}\" />";

	}

	$handles = '';

	foreach($m['platform']['handles'] as $h) {

		$handles .= "\r\n\t\t\t<message type=\"{$h}\" />";

	}

	$rule = $m['platform']['rule'] ? 'true' : 'false';

	$card = $m['platform']['card'] ? 'true' : 'false';

	$bindings = '';

	global $points;

	foreach($points as $p => $row) {

		if(is_array($m['bindings'][$p]) && !empty($m['bindings'][$p])) {

			$piece = "\r\n\t\t<{$p}>";

			foreach($m['bindings'][$p] as $entry) {

				$direct = $entry['direct'] ? 'true' : 'false';

				$piece .= "\r\n\t\t\t<entry title=\"{$entry['title']}\" do=\"{$entry['do']}\" state=\"{$entry['state']}\" direct=\"{$direct}\" />";

			}

			$piece .= "\r\n\t\t</{$p}>";

			$bindings .= $piece;

		}

	}

	if(is_array($m['permission']) && !empty($m['permission'])) {

		$permissions = '';

		foreach($m['permission'] as $entry) {

			$piece .= "\r\n\t\t\t<entry title=\"{$entry['title']}\" do=\"{$entry['permission']}\" />";

		}

		$permissions .= $piece;

	}

	$tpl = <<<TPL

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns="http://www.qincewang.com" versionCode="{$versions}">

	<application setting="{$setting}">

		<name><![CDATA[{$m['application']['name']}]]></name>

		<identifie><![CDATA[{$m['application']['identifie']}]]></identifie>

		<version><![CDATA[{$m['application']['version']}]]></version>

		<type><![CDATA[{$m['application']['type']}]]></type>

		<ability><![CDATA[{$m['application']['ability']}]]></ability>

		<description><![CDATA[{$m['application']['description']}]]></description>

		<author><![CDATA[{$m['application']['author']}]]></author>

		<url><![CDATA[{$m['application']['url']}]]></url>

	</application>

	<platform>

		<subscribes>{$subscribes}

		</subscribes>

		<handles>{$handles}

		</handles>

		<rule embed="{$rule}" />

		<card embed="{$card}" />

	</platform>

	<bindings>{$bindings}

	</bindings>

	<permissions>{$permissions}

	</permissions>

	<install><![CDATA[{$m['install']}]]></install>

	<uninstall><![CDATA[{$m['uninstall']}]]></uninstall>

	<upgrade><![CDATA[{$m['upgrade']}]]></upgrade>

</manifest>

TPL;

	return ltrim($tpl);

}



function define_module($m) {

	$name = ucfirst($m['application']['identifie']);



	$rule = '';

	if($m['platform']['rule']) {

		$rule = <<<TPL

	public function fieldsFormDisplay(\$rid = 0) {

		//要嵌入规则编辑页的自定义内容，这里 \$rid 为对应的规则编号，新增时为 0

	}



	public function fieldsFormValidate(\$rid = 0) {

		//规则编辑保存时，要进行的数据验证，返回空串表示验证无误，返回其他字符串将呈现为错误提示。这里 \$rid 为对应的规则编号，新增时为 0

		return '';

	}



	public function fieldsFormSubmit(\$rid) {

		//规则验证无误保存入库时执行，这里应该进行自定义字段的保存。这里 \$rid 为对应的规则编号

	}



	public function ruleDeleted(\$rid) {

		//删除规则时调用，这里 \$rid 为对应的规则编号

	}



TPL;

	}



	$setting = '';

	if($m['application']['setting']) {

		$setting = <<<TPL

	public function settingsDisplay(\$settings) {

		global \$_W, \$_GPC;

		//点击模块设置时将调用此方法呈现模块设置页面，\$settings 为模块设置参数, 结构为数组。这个参数系统针对不同公众账号独立保存。

		//在此呈现页面中自行处理post请求并保存设置参数（通过使用\$this->saveSettings()来实现）

		if(checksubmit()) {

			//字段验证, 并获得正确的数据\$dat

			\$this->saveSettings(\$dat);

		}

		//这里来展示设置项表单

		include \$this->template('setting');

	}



TPL;

	}



	$tpl = <<<TPL

<?php

/**

 * {$m['application']['name']}模块定义

 *

 * @author {$m['application']['author']}

 * @url {$m['application']['url']}

 */

defined('IN_IA') or exit('Access Denied');



class {$name}Module extends WeModule {

{$rule}

{$setting}

}

TPL;

	return ltrim($tpl);

}



function define_processor($m) {

	$name = ucfirst($m['application']['identifie']);

	$tpl = '';

	if($m['platform']['handles']) {

	$tpl = <<<TPL

<?php

/**

 * {$m['application']['name']}模块处理程序

 *

 * @author {$m['application']['author']}

 * @url {$m['application']['url']}

 */

defined('IN_IA') or exit('Access Denied');



class {$name}ModuleProcessor extends WeModuleProcessor {

	public function respond() {

		\$content = \$this->message['content'];

		//这里定义此模块进行消息处理时的具体过程, 请查看微擎文档来编写你的代码

	}

}

TPL;

	}

	return ltrim($tpl);

}



function define_receiver($m) {

	$name = ucfirst($m['application']['identifie']);

	$tpl = '';

	if($m['platform']['subscribes']) {

	$tpl = <<<TPL

<?php

/**

 * {$m['application']['name']}模块订阅器

 *

 * @author {$m['application']['author']}

 * @url {$m['application']['url']}

 */

defined('IN_IA') or exit('Access Denied');



class {$name}ModuleReceiver extends WeModuleReceiver {

	public function receive() {

		\$type = \$this->message['type'];

		//这里定义此模块进行消息订阅时的, 消息到达以后的具体处理过程, 请查看微擎文档来编写你的代码

	}

}

TPL;

	}

	return ltrim($tpl);

}



function define_site($m) {

	global $points;

	$name = ucfirst($m['application']['identifie']);

	$tpl = '';



	$dos = '';

	if(is_array($m['bindings']) && !empty($m['bindings'])) {

		$webdos = array();

		$appdos = array();

		foreach($points as $p => $row) {

			if(!empty($m['bindings'][$p]) && in_array($p, array('rule', 'menu'))) {

				foreach($m['bindings'][$p] as $opt) {

					if(in_array($opt['do'], $webdos)){

						continue;

					}

					$webdos[] = $opt['do'];

					$dName = ucfirst($opt['do']);

					$dos .= <<<TPL

	public function doWeb{$dName}() {

		//这个操作被定义用来呈现 {$row['title']}

	}



TPL;

				}

			}

			if(!empty($m['bindings'][$p]) && in_array($p, array('cover', 'home', 'profile', 'shortcut'))) {

				foreach($m['bindings'][$p] as $opt) {

					if(in_array($opt['do'], $appdos)){

						continue;

					}

					$appdos[] = $opt['do'];

					$dName = ucfirst($opt['do']);

					$dos .= <<<TPL

	public function doMobile{$dName}() {

		//这个操作被定义用来呈现 {$row['title']}

	}



TPL;

				}

			}

		}

		$tpl = <<<TPL

<?php

/**

 * {$m['application']['name']}模块微站定义

 *

 * @author {$m['application']['author']}

 * @url {$m['application']['url']}

 */

defined('IN_IA') or exit('Access Denied');



class {$name}ModuleSite extends WeModuleSite {



{$dos}

}

TPL;

	}



	return ltrim($tpl);

}



function f_write($filename, $data) {

	global $_W;

	mkdirs(dirname($filename));

	file_put_contents($filename, $data);

	@chmod($filename, $_W['config']['setting']['filemode']);

	return is_file($filename);

}



function update_handle($module = '') {

	$isupdate = 0;

	if(file_exists(IA_ROOT . '/data/modules_log.php')) {

		$isupdate = 1;

	}

	if(!$isupdate || empty($module)) {

		return true;

	} else {

		@require IA_ROOT . '/data/modules_log.php';

		if(!empty($module_log)) {

			if(isset($module_log[$module])) {

				pdo_update('modules', array('version' => $module_log[$module]), array('name' => $module));

				unset($module_log[$module]);

			}



			if(empty($module_log)) {

				@unlink(IA_ROOT . '/data/modules_log.php');

			} else {

				$content_update = "<?php\r\n";

				$content_update .= "\$module_log = " . var_export($module_log, true) . ";\r\n";

				$content_update .= "?>";

				file_put_contents(IA_ROOT . '/data/modules_log.php', $content_update);

			}

		} else {

			@unlink(IA_ROOT . '/data/modules_log.php');

		}

		return true;

	}

}

